/**
 * Created by way on 2016/12/6.
 */

import { format } from './kutil';

export default class Ws {
  static Status = {
    close: 0,
    open: 1,
    opened: 2
  };

  /**
   * 构造函数
   * @param {*} opt 选项
   * {url:'xxx',pid:'xxx',time:10}
   * ws 服务器，自身pid，心跳时长多少秒
   */
  constructor(opt) {
    this.opt = opt || {};
    this.status = Ws.Status.close;
    this.url = this.opt.url || `ws://${location.host}`;
    this.pid = this.opt.pid || '';
    this.heartTm = this.opt.time || 10;
    this.ws = this.open();
    this.tm = null;
    this.status = Ws.Status.open;
  }

  open(cb) {
    if (!WebSocket) {
      alert('WebSocket not supported!');
      return null;
    }

    // alert(location.host);
    const ws = new WebSocket(this.url); // `ws://${location.host}`
    if (ws) {
      ws.onopen = w => {
        // log('opened...');
        ws.send('Hello WebSocket!');
        this.status = Ws.Status.opened;

        if (this.onopen)
          this.onopen(w);

        if (cb)
          cb();

        setTimeout(() => {
          this.heart();
        }, 2000);

        // ws.binaryType = "arraybuffer";
        // var a new Unit8Array([8,6,7,5,3,0,9]);
        // ws.send(a.buffer );
      };

      ws.onmessage = w => {
        // console.log(e);
        if (this.onmsg)
          this.onmsg(w.data.toString());
      };

      ws.onclose = w => {
        // log('closed.');
        this.status = Ws.Status.close;
        if (this.onclose)
          this.onclose(w);
        this.ws = null;
      };

      ws.onerror = w => {
        // log('error!');
        if (this.onerror)
          this.onerror();
      };
    } else
      alert('连接消息服务器失败！');

    return ws;
  }

  send(s) {
    if (this.ws) {
      this.ws.send(s);
    } else {
      this.ws = this.open(() => {
        if (this.ws) {
          this.ws.send(s);
        }
      });
    }
  }

  // 注册
  // reg(s = '1,""') {
  //   s = format('{"R":[%s], "F":"%s"}', s, this.pid);
  //   this.send(s);
  // }

  // 10 秒一次心跳，如果没有打开ws，重新打开
  heart() {
    var msg = '[[1,""]]';
    msg = format('{"H":%s, "F":"%s"}', msg, this.pid);
    this.send(msg);
    this.tm = setTimeout(() => {
      this.heart();
    }, this.heartTm * 1000);
  }

  // 订阅 状态 1/0
  sub(t, s) {
    const msg = format('{"S":%d, "F":"%s", "T":"%s"}',
      s, this.pid, t);
    this.send(msg);
  }

  // 消息
  msg(t, s, fw, tp, sq, st) {
    let msg = s || '';
    msg = msg.replace(/([^\\])"/g, '$1\\"');  // /(?<!\\)"/g 不支持
    let tm = parseInt(new Date().getTime() - Date.parse('2000/01/01'));
    msg = format('{"M":"%s", "F":"%s", "T":"%s", "FW":"%s", "TP":"%s", "TM":%d, "SQ":%d, "ST":%d}',
      msg, this.pid, t, fw || '', tp || '', tm, sq || '', st || '');
    this.send(msg);
  }

  // 群发
  group(t, s, fw, tp, sq, st) {
    let msg = s;
    msg = msg.replace(/([^\\])"/g, '$1\\"');  // /(?<!\\)"/g 不支持
    let tm = parseInt(new Date().getTime() - Date.parse('2000/01/01'));
    msg = format('{"M.G":"%s", "F":"%s", "T":"%s", "FW":"%s", "TP":"%s", "TM":%d, "SQ":%d, "ST":%d}',
      msg, this.pid, t, fw || '', tp || '', tm, sq || '', st || '');
    this.send(msg);
  }

  // 信息
  info(t, s) {
    let msg = s;
    msg = msg.replace(/([^\\])"/g, '$1\\"');  // /(?<!\\)"/g 不支持
    msg = format('{"I":"%s", "F":"%s", "T":"%s"}',
      msg, this.pid, t);
    this.send(msg);
  }

  // 抢答
  answer(t, s) {
    let msg = s;
    msg = msg.replace(/([^\\])"/g, '$1\\"');  // /(?<!\\)"/g 不支持
    msg = format('{"M.A":"%s", "F":"%s", "T":"%s"}',
      msg, this.pid, t);
    this.send(msg);
  }

  // 标签广播
  tag(t, s) {
    let msg = s;
    msg = msg.replace(/([^\\])"/g, '$1\\"');  // /(?<!\\)"/g 不支持
    msg = format('{"M.T":"%s", "F":"%s", "T":"%s"}',
      msg, this.pid, t);
    this.send(msg);
  }

  // 关闭
  close() {
    if (this.tm)
      clearTimeout(this.tm);

    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }
  }
  //测试用的正式这个去掉
  close2() {
    this.ws.close();
  }
}
